package cn.gorit.advice;

import cn.gorit.common.enums.ResultEnums;
import cn.gorit.common.exception.*;
import cn.gorit.common.lang.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.IOException;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @version v1.0
 * @Classname GlobalExceptionAdvice
 * @Description 统一全局异常处理
 * @Author Gorit
 * @Created by 2021/3/21 23:28
 * @IDLE IntelliJ IDEA
 **/
@RestControllerAdvice
public class GlobalExceptionAdvice {
    private final Logger log = LoggerFactory.getLogger(GlobalExceptionAdvice.class);

    // 拦截用户自定义异常
    @ExceptionHandler(BlogException.class)
    public Result<Object> blogExceptionHandler(BlogException ex) {
        log.error("【内容模块】相关异常: {}",ex.getMessage());
        return new Result<>(ex.getErrorCode(),ex.getMessage());
    }

    // 拦截用户自定义异常
    @ExceptionHandler(UserException.class)
    public Result<Object> userExceptionHandler(UserException ex) {
        log.error("【用户模块】相关异常: {}",ex.getMessage());
        return new Result<>(ex.getErrorCode(),ex.getMessage());
    }

    // 处理管理员相关异常
    @ExceptionHandler(AdminException.class)
    public Result<Object> adminExceptionHandler(AdminException e) {
        log.error("【管理员模块】相关异常: {}",e.getMessage());
        return new Result<>(e.getErrorCode(),e.getMessage());
    }

    @ExceptionHandler(SystemException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public Result handleSystemException(SystemException e) {
        log.error("【系统模块】相关异常: {}",e.getMessage());
        return new Result(e.getErrorCode(),e.getMessage());
    }

    @ExceptionHandler(ResourceException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public Result handleResourceException(ResourceException e) {
        log.error("【资源模块】发生异常: {}",e.getMessage());
        return new Result(e.getErrorCode(),e.getMessage());
    }

    //    空指针异常
    @ExceptionHandler(NullPointerException.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public Result handleTypeMismatchException(NullPointerException ex) {
        log.error("空指针异常: {}",ex.getMessage());
        return new Result(ResultEnums.NULL_POINTER.getCode(),ResultEnums.NULL_POINTER.getMsg());
    }

    // SQL 语句异常
    @ExceptionHandler(SQLException.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public Result handSQLException(SQLException sql) {
        log.error("SQL 语句异常: {}",sql.getMessage());
        return new Result(ResultEnums.SQL_ERROR.getCode(),ResultEnums.SQL_ERROR.getMsg());
    }

    // 请求方法不存在
    @ExceptionHandler(NoSuchMethodException.class)
    @ResponseStatus(value = HttpStatus.METHOD_NOT_ALLOWED)
    public Result handleNoSuchMethodException(NoSuchMethodException exc) {
        log.error("请求方法不存在 {}",exc.getMessage());
        return new Result(ResultEnums.METHOD_NOT_ALLOWED.getCode(),ResultEnums.METHOD_NOT_ALLOWED.getMsg());
    }

    // 数据格式不正确
    @ExceptionHandler(NumberFormatException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public Result handleNumberFormatException(NumberFormatException ex) {
        log.error("数据格式问题 {}",ex.getMessage());
        return new Result(50000,"请检查你的数据格式是否正确");
    }

    // IO 操作
    @ExceptionHandler(IOException.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public Result handleIOException(IOException e) {
        log.error("文件读写出错: {}", e.getMessage());
        return new Result(ResultEnums.IO_ERROR.getCode(),ResultEnums.IO_ERROR.getMsg());
    }

    @ExceptionHandler(IllegalStateException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public Result handleIllegalStateException(IllegalStateException e) {
        log.error("请求参数格式出错: {}",e.getMessage());
        return new Result(ResultEnums.PARAMS_ERROR.getCode(),ResultEnums.PARAMS_ERROR.getMsg());
    }

    // SQL 主键或者唯一约束冲突
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public Result handleSQLIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException e) {
        log.error("SQL 唯一冲突: {}",e.getMessage());
        return new Result(ResultEnums.SQL_UNIKEY_ERROR.getCode(),ResultEnums.SQL_UNIKEY_ERROR.getMsg());
    }

}
